/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.digitalization.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Triple;
import org.springblade.common.constant.LogConstant;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.excel.util.ExcelUtil;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tenant.annotation.TenantIgnore;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.FileUtils;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.digitalization.dto.MuluExportDTO;
import org.springblade.modules.digitalization.dto.RsdamlPageChangeDTO;
import org.springblade.modules.digitalization.dto.RsdamlPageUpdateDTO;
import org.springblade.modules.digitalization.dto.SelectRsdamlRead;
import org.springblade.modules.digitalization.entity.A01Entity;
import org.springblade.modules.digitalization.entity.ManageArchivesEntity;
import org.springblade.modules.digitalization.entity.ManageRsdamlEntity;
import org.springblade.modules.digitalization.entity.UmsUserInfoEntity;
import org.springblade.modules.digitalization.excel.ManageRsdamlExcel;
import org.springblade.modules.digitalization.manager.LogManager;
import org.springblade.modules.digitalization.service.IManageArchivesService;
import org.springblade.modules.digitalization.service.IManageRsdamlService;
import org.springblade.modules.digitalization.service.IUmsUserInfoService;
import org.springblade.modules.digitalization.service.impl.A01ServiceImpl;
import org.springblade.modules.digitalization.utils.DaUtils;
import org.springblade.modules.digitalization.utils.ExcelExportUtil;
import org.springblade.modules.digitalization.vo.A01VO;
import org.springblade.modules.digitalization.vo.CatalogItem;
import org.springblade.modules.digitalization.vo.ManageRsdamlVO;
import org.springblade.modules.digitalization.wrapper.A01Wrapper;
import org.springblade.modules.digitalization.wrapper.ManageRsdamlWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 干部人事档案目录信息表-JAVA 控制器
 *
 * @author Rs
 * @since 2023-01-07
 */
@Slf4j
@RestController
@RequestMapping("blade-rsdaml/rsdaml")
@Api(value = "干部人事档案目录信息表-JAVA", tags = "干部人事档案目录信息表-JAVA接口")
public class ManageRsdamlController extends BladeController {

	@Autowired
	private IManageRsdamlService rsdamlService;

	@Autowired
	private IManageArchivesService archivesService;

	@Autowired
	private LogManager logManager;
	@Autowired
	private A01ServiceImpl a01ServiceImpl;

	/**
	 * 干部人事档案目录信息表-JAVA 详情
	 */
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入rsdaml")
	public R<ManageRsdamlVO> detail(ManageRsdamlEntity rsdaml) {
		ManageRsdamlEntity detail = rsdamlService.getOne(Condition.getQueryWrapper(rsdaml));
		return R.data(ManageRsdamlWrapper.build().entityVO(detail));
	}

	/**
	 * 干部人事档案目录信息表-JAVA 分页
	 */
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入rsdaml")
	public R<IPage<ManageRsdamlVO>> list(ManageRsdamlEntity rsdaml, Query query) {
		IPage<ManageRsdamlEntity> pages = rsdamlService.page(Condition.getPage(query), Condition.getQueryWrapper(rsdaml).orderByAsc("class_sort").orderByAsc("rsdaml003"));
		return R.data(ManageRsdamlWrapper.build().pageVO(pages));
	}


	@GetMapping("/list/ids")
	public R<List<ManageRsdamlVO>> list(@RequestParam("ids") String ids) {
		List<ManageRsdamlEntity> byA0000 = rsdamlService.getByRsdaml000(Func.toStrList(ids));
		return R.data(ManageRsdamlWrapper.build().listVO(byA0000));
	}


	@Value("${archive.tempPath:/tmp}")
	private String tempPath;

	@Autowired
	private IUmsUserInfoService umsUserInfoService;

	/**
	 * 导出数据
	 */
	@PostMapping("/download-redaml")
	public void exportRsdaml(@RequestBody MuluExportDTO muluExportDTO, HttpServletResponse response) throws IOException {

		String baseDir = tempPath + "/" + UUID.fastUUID();
		FileUtil.mkParentDirs(baseDir);

		List<String> ids = muluExportDTO.getIds();
		if (StringUtil.isNotBlank(muluExportDTO.getB0111())) {
			ids = a01ServiceImpl
				.list(Wrappers.<A01Entity>lambdaQuery().likeRight(A01Entity::getA0195, muluExportDTO.getB0111()))
				.stream()
				.map(A01Entity::getId)
				.map(String::valueOf)
				.collect(Collectors.toList());
		}
		List<String> collect = ids.stream().map(userId -> {
			try {
				return exportMulu(userId, muluExportDTO.getDict(), baseDir, muluExportDTO.getConfig());
			} catch (Exception e) {
				log.error(e.getMessage(), e);
				return null;
			}
		}).filter(Objects::nonNull).collect(Collectors.toList());
		log.info("export xlsx files:{}", collect);
		if(collect.size()==1){
			String fileName = FileUtil.getName(collect.get(0));
			String filePath = collect.get(0);
			FileUtils.setAttachmentResponseHeader(response, fileName);
			FileUtils.writeBytes(filePath, response.getOutputStream());
		}else{
			exportZip(response, baseDir);
		}
		FileUtil.del(baseDir);
	}

	private void exportZip(HttpServletResponse response, String baseDir) throws IOException {
		String fileName = String.format("档案目录-%s.zip", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
		String filePath = String.format("%s/%s", tempPath, fileName);
		if (FileUtil.exist(filePath)) {
			FileUtil.del(filePath);
		}
		DaUtils.compressFolder(baseDir, filePath);
		FileUtils.setAttachmentResponseHeader(response, fileName);
		FileUtils.writeBytes(filePath, response.getOutputStream());
	}

	private String exportMulu(String userId, List<Map<String, String>> dict, String baseDir, String config) {
		UmsUserInfoEntity userInfoEntity = umsUserInfoService.getById(userId);
		ManageRsdamlEntity manageRsdamlEntity = new ManageRsdamlEntity();
		manageRsdamlEntity.setA0000(userInfoEntity.getA0000());

		QueryWrapper<ManageRsdamlEntity> query = Condition.getQueryWrapper(manageRsdamlEntity).orderByAsc("class_sort").orderByAsc("rsdaml003");
		List<ManageRsdamlEntity> list = rsdamlService.list(query);
		String fileName = String.format("档案目录-%s-%s.xlsx", userInfoEntity.getA0101(), userInfoEntity.getA0184());
		String filePath = String.format("%s/%s", baseDir, fileName);
		ExcelExportUtil.exportData(list, dict, userInfoEntity.getA0101(), filePath, config);
		return filePath;
	}


	/**
	 * 干部人事档案目录信息表-JAVA 分页
	 */
	@GetMapping("/listWithWj")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入rsdaml")
	public R<List<ManageRsdamlVO>> listWithPage(ManageRsdamlEntity rsdaml) {
		List<ManageRsdamlVO> pages = rsdamlService.listWithPage(rsdaml);
		return R.data(pages);
	}


	/**
	 * 干部人事档案目录信息表-JAVA 自定义分页
	 */
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入rsdaml")
	public R<IPage<ManageRsdamlVO>> page(ManageRsdamlVO rsdaml, Query query) {
		IPage<ManageRsdamlVO> pages = rsdamlService.selectManageRsdamlPage(Condition.getPage(query), rsdaml);
		return R.data(pages);
	}

	@PostMapping("/savesort")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入b01")
	public R saveSort(@Valid @RequestBody List<ManageRsdamlEntity> manageRsdamlEntities) {
		List<ManageRsdamlEntity> oldDatas = rsdamlService.listByIds(manageRsdamlEntities.stream().map(ManageRsdamlEntity::getId).collect(Collectors.toList()));

		manageRsdamlEntities.stream().forEach(DaUtils::convertChineseRightQuote);
		manageRsdamlEntities.stream().forEach(ManageRsdamlController::updateFormationTime);


		boolean b = rsdamlService.updateBatchById(manageRsdamlEntities);

		if (manageRsdamlEntities.isEmpty() == false) {
			manageRsdamlEntities.stream().forEach(newData -> {
				oldDatas.stream()
					.filter(oldData -> oldData.getId().equals(newData.getId()))
					.findAny().ifPresent(oldData -> {
						logManager.doUpdate(newData.getA0000(), LogManager.TYPE_ML, oldData, newData);
					});
			});
		}
		return R.status(b);
	}

	/**
	 * 干部人事档案目录信息表-JAVA 新增
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入rsdaml")
	public R save(@Valid @RequestBody ManageRsdamlEntity rsdaml) {
		DaUtils.convertChineseRightQuote(rsdaml);
		return R.status(rsdamlService.saveManageRsdamlEntity(rsdaml));
	}

	/**
	 * 干部人事档案目录信息表-JAVA 修改
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入rsdaml")
	@Deprecated
	public R update(@Valid @RequestBody ManageRsdamlEntity rsdaml) {
		DaUtils.convertChineseRightQuote(rsdaml);
		return R.status(rsdamlService.updateManageRsdamlEntity(rsdaml));
	}

	/**
	 * 干部人事档案目录信息表-JAVA 新增或修改
	 */
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入rsdaml")
	public R submit(@Valid @RequestBody ManageRsdamlEntity rsdaml) {
		DaUtils.convertChineseRightQuote(rsdaml);
		if (Func.isEmpty(rsdaml.getId())) {
			ManageArchivesEntity one = archivesService.getOne(Wrappers.<ManageArchivesEntity>lambdaQuery().eq(ManageArchivesEntity::getA0000, rsdaml.getA0000()).eq(ManageArchivesEntity::getIsDeleted, 0));
			rsdaml.setArchiveId(one.getArchiveId());
			rsdaml.setRsdaml000(IdUtil.randomUUID());
		}
		this.updateFormationTime(rsdaml);
		Integer classMap = rsdamlService.getClassMap(rsdaml.getRsdaml002());
		rsdaml.setClassSort(classMap);
		return R.status(rsdamlService.saveOrUpdateManageRsdamlEntity(rsdaml));
	}

	@PostMapping("/page/submit")
	@Deprecated
	public R changePageCount(@RequestBody RsdamlPageUpdateDTO list) {
		int i = rsdamlService.changePageCount(list);
		return R.status(i >= 1);
	}


	@PutMapping("/pageNo")
	public R changePageNo(@RequestBody RsdamlPageChangeDTO pageChangeDTO) {
		int i = rsdamlService.changePageNo(pageChangeDTO);
		return R.status(i >= 1);
	}

	/**
	 * 干部人事档案目录信息表-JAVA 删除
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(rsdamlService.removeManageRsdamlEntity(Func.toLongList(ids)));
	}

	/**
	 * 获取档案全部目录
	 */
	@PostMapping("/getAllMulu")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "获取档案全部目录 v1", notes = "传入a0000,serialNumber")
	public R<List<CatalogItem>> selectRsdamlAll(@RequestBody SelectRsdamlRead selectRsdamlRead) {
		return R.data(rsdamlService.slectCatalogItem(selectRsdamlRead));
	}

	@PostMapping("/import")
	@ApiOperationSupport(order = 1)
	@TenantIgnore
	@ApiOperation(value = "目录导入", notes = "上传excel")
	public R<List<ManageRsdamlExcel>> importA01(MultipartFile file,
												@RequestParam String a0000,
												@RequestParam(value = "status", defaultValue = "1") Integer status,
												HttpServletResponse response) {
		try {
			List<ManageRsdamlExcel> a01ArchiveEntity = rsdamlService.doImport(file, a0000, status);
			return R.data(a01ArchiveEntity);
		} catch (Exception e) {
			return R.fail(e.getMessage());
		}
	}

	/**
	 * 导出数据
	 */
	@GetMapping("/exportError")
	@ApiOperationSupport(order = 9)
	@ApiOperation(value = "导出数据", notes = "传入a01")
	public void exportErrorData(String a0000, HttpServletResponse response) {
		List<ManageRsdamlExcel> errorData = rsdamlService.getMlErrorMaps(a0000);
		ExcelUtil.export(response, "错误人员数据" + DateUtil.time(), "错误人员数据", errorData, ManageRsdamlExcel.class);
//		ServletUtil.write();
	}

	private static void updateFormationTime(ManageRsdamlEntity rsdaml) {
		if (Func.isNotEmpty(rsdaml.getFormationTime())) {
			Triple<String, String, String> date = ExcelExportUtil.getDate(rsdaml.getFormationTime());
			rsdaml.setRsdaml006(date.getLeft());
			rsdaml.setRsdaml007(date.getMiddle());
			rsdaml.setRsdaml008(date.getRight());
		} else {
			rsdaml.setRsdaml006("");
			rsdaml.setRsdaml007("");
			rsdaml.setRsdaml008("");
		}
	}
}
